home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * triangle.c
- *
- * This module implements primitives for triangles and smooth triangles.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "matrices.h"
- #include "objects.h"
- #include "triangle.h"
-
-
-
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
-
- #define DEPTH_TOLERANCE 1e-6
-
- #define max3_coordinate(x,y,z) \
- ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
-
-
-
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
-
- static void find_triangle_dominant_axis PARAMS((TRIANGLE *Triangle));
- static void compute_smooth_triangle PARAMS((SMOOTH_TRIANGLE *Triangle));
- static int Intersect_Triangle PARAMS((RAY *Ray, TRIANGLE *Triangle, DBL *Depth));
- static int All_Triangle_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
- static int Inside_Triangle PARAMS((VECTOR IPoint, OBJECT *Object));
- static void Triangle_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
- static void *Copy_Triangle PARAMS((OBJECT *Object));
- static void Translate_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Rotate_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Scale_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Transform_Triangle PARAMS((OBJECT *Object, TRANSFORM *Trans));
- static void Invert_Triangle PARAMS((OBJECT *Object));
- static void Smooth_Triangle_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
- static void *Copy_Smooth_Triangle PARAMS((OBJECT *Object));
- static void Translate_Smooth_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Rotate_Smooth_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Scale_Smooth_Triangle PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Transform_Smooth_Triangle PARAMS((OBJECT *Object, TRANSFORM *Trans));
- static void Invert_Smooth_Triangle PARAMS((OBJECT *Object));
- static void Destroy_Triangle PARAMS((OBJECT *Object));
-
-
-
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
-
- METHODS Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Triangle_Normal,
- Copy_Triangle,
- Translate_Triangle, Rotate_Triangle,
- Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
- };
-
- METHODS Smooth_Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Smooth_Triangle_Normal,
- Copy_Smooth_Triangle,
- Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
- Scale_Smooth_Triangle, Transform_Smooth_Triangle,
- Invert_Smooth_Triangle, Destroy_Triangle
- };
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * find_triangle_dominant_axis
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void find_triangle_dominant_axis(Triangle)
- TRIANGLE *Triangle;
- {
- DBL x, y, z;
-
- x = fabs(Triangle->Normal_Vector[X]);
- y = fabs(Triangle->Normal_Vector[Y]);
- z = fabs(Triangle->Normal_Vector[Z]);
-
- Triangle->Dominant_Axis = max3_coordinate(x, y, z);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * compute_smooth_triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void compute_smooth_triangle(Triangle)
- SMOOTH_TRIANGLE *Triangle;
- {
- VECTOR P3MinusP2, VTemp1, VTemp2;
- DBL x, y, z, uDenominator, Proj;
-
- VSub(P3MinusP2, Triangle->P3, Triangle->P2);
-
- x = fabs(P3MinusP2[X]);
- y = fabs(P3MinusP2[Y]);
- z = fabs(P3MinusP2[Z]);
-
- Triangle->vAxis = max3_coordinate(x, y, z);
-
- VSub(VTemp1, Triangle->P2, Triangle->P3);
-
- VNormalize(VTemp1, VTemp1);
-
- VSub(VTemp2, Triangle->P1, Triangle->P3);
-
- VDot(Proj, VTemp2, VTemp1);
-
- VScaleEq(VTemp1, Proj);
-
- VSub(Triangle->Perp, VTemp1, VTemp2);
-
- VNormalize(Triangle->Perp, Triangle->Perp);
-
- VDot(uDenominator, VTemp2, Triangle->Perp);
-
- VInverseScaleEq(Triangle->Perp, -uDenominator);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- int Compute_Triangle(Triangle,Smooth)
- TRIANGLE *Triangle;
- int Smooth;
- {
- int swap;
- VECTOR V1, V2, Temp;
- DBL Length;
-
- VSub(V1, Triangle->P1, Triangle->P2);
- VSub(V2, Triangle->P3, Triangle->P2);
-
- VCross(Triangle->Normal_Vector, V1, V2);
-
- VLength(Length, Triangle->Normal_Vector);
-
- /* Set up a flag so we can ignore degenerate triangles */
-
- if (Length == 0.0)
- {
- Set_Flag(Triangle, DEGENERATE_FLAG);
-
- return(FALSE);
- }
-
- /* Normalize the normal vector. */
-
- VInverseScaleEq(Triangle->Normal_Vector, Length);
-
- VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
-
- Triangle->Distance *= -1.0;
-
- find_triangle_dominant_axis(Triangle);
-
- swap = FALSE;
-
- switch (Triangle->Dominant_Axis)
- {
- case X:
-
- if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
- {
- swap = TRUE;
- }
-
- break;
-
- case Y:
-
- if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
- {
- swap = TRUE;
- }
-
- break;
-
- case Z:
-
- if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
- (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
- {
- swap = TRUE;
- }
-
- break;
- }
-
- if (swap)
- {
- Assign_Vector(Temp, Triangle->P2);
- Assign_Vector(Triangle->P2, Triangle->P1);
- Assign_Vector(Triangle->P1, Temp);
-
- if (Smooth)
- {
- Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
- Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
- Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
- }
- }
-
- if (Smooth)
- {
- compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
- }
-
- /* Build the bounding information from the vertices. */
-
- Compute_Triangle_BBox(Triangle);
-
- return(TRUE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_Triangle_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static int All_Triangle_Intersections(Object, Ray, Depth_Stack)
- OBJECT *Object;
- RAY *Ray;
- ISTACK *Depth_Stack;
- {
- DBL Depth;
- VECTOR IPoint;
-
- if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
- {
- VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
-
- if (Point_In_Clip(IPoint,Object->Clip))
- {
- push_entry(Depth,IPoint,Object,Depth_Stack);
-
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Intersect_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static int Intersect_Triangle(Ray, Triangle, Depth)
- RAY *Ray;
- TRIANGLE *Triangle;
- DBL *Depth;
- {
- DBL NormalDotOrigin, NormalDotDirection;
- DBL s, t;
-
- Increase_Counter(stats[Ray_Triangle_Tests]);
-
- if (Test_Flag(Triangle, DEGENERATE_FLAG))
- {
- return(FALSE);
- }
-
- VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
-
- if (fabs(NormalDotDirection) < EPSILON)
- {
- return(FALSE);
- }
-
- VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
-
- *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
-
- if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
- {
- return(FALSE);
- }
-
- switch (Triangle->Dominant_Axis)
- {
- case X:
-
- s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
- t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
-
- if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
- (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
- (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
- {
- return(FALSE);
- }
-
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
-
- return(TRUE);
-
- case Y:
-
- s = Ray->Initial[X] + *Depth * Ray->Direction[X];
- t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
-
- if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
- (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
- (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
- {
- return(FALSE);
- }
-
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
-
- return(TRUE);
-
- case Z:
-
- s = Ray->Initial[X] + *Depth * Ray->Direction[X];
- t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
-
- if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
- (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
- (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
- {
- return(FALSE);
- }
-
- if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
- (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
- {
- return(FALSE);
- }
-
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
-
- return(TRUE);
- }
-
- return(FALSE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static int Inside_Triangle(IPoint, Object)
- VECTOR IPoint;
- OBJECT *Object;
- {
- return(FALSE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Triangle_Normal
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Triangle_Normal(Result, Object, Inter)
- OBJECT *Object;
- VECTOR Result;
- INTERSECTION *Inter;
- {
- Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Smooth_Triangle_Normal
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * Calculate the Phong-interpolated vector within the triangle
- * at the given intersection point. The math for this is a bit
- * bizarre:
- *
- * - P1
- * | /|\ \
- * | / |Perp\
- * | / V \ \
- * | / | \ \
- * u | /____|_____PI___\
- * | / | \ \
- * - P2-----|--------|----P3
- * Pbase PIntersect
- * |-------------------|
- * v
- *
- * Triangle->Perp is a unit vector from P1 to Pbase. We calculate
- *
- * u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
- *
- * We then calculate where the line from P1 to PI intersects the line P2 to P3:
- * PIntersect = (PI - P1)/u.
- *
- * We really only need one coordinate of PIntersect. We then calculate v as:
- *
- * v = PIntersect[X] / (P3[X] - P2[X])
- * or v = PIntersect[Y] / (P3[Y] - P2[Y])
- * or v = PIntersect[Z] / (P3[Z] - P2[Z])
- *
- * depending on which calculation will give us the best answers.
- *
- * Once we have u and v, we can perform the normal interpolation as:
- *
- * NTemp1 = N1 + u(N2 - N1);
- * NTemp2 = N1 + u(N3 - N1);
- * Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
- *
- * As always, any values which are constant for the triangle are cached
- * in the triangle.
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Smooth_Triangle_Normal(Result, Object, Inter)
- OBJECT *Object;
- VECTOR Result;
- INTERSECTION *Inter;
- {
- int Axis;
- DBL u, v;
- VECTOR PIMinusP1;
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
-
- VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
-
- VDot(u, PIMinusP1, Triangle->Perp);
-
- if (u < EPSILON)
- {
- Assign_Vector(Result, Triangle->N1);
- return;
- }
-
- Axis = Triangle->vAxis;
-
- v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
-
- /* This is faster. [DB 8/94] */
-
- Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
- Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
- Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
-
- VNormalize(Result, Result);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Translate_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- TRIANGLE *Triangle = (TRIANGLE *)Object;
- VECTOR Translation;
-
- if (!Test_Flag(Triangle, DEGENERATE_FLAG))
- {
- VEvaluate(Translation, Triangle->Normal_Vector, Vector);
-
- Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
-
- VAddEq(Triangle->P1, Vector);
- VAddEq(Triangle->P2, Vector);
- VAddEq(Triangle->P3, Vector);
-
- Compute_Triangle(Triangle, FALSE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Rotate_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Transform_Triangle(Object, Trans);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Scale_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- DBL Length;
- TRIANGLE *Triangle = (TRIANGLE *)Object;
-
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
- Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
- Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
-
- VLength(Length, Triangle->Normal_Vector);
-
- VInverseScaleEq(Triangle->Normal_Vector, Length);
-
- Triangle->Distance /= Length;
-
- VEvaluateEq(Triangle->P1, Vector);
- VEvaluateEq(Triangle->P2, Vector);
- VEvaluateEq(Triangle->P3, Vector);
-
- Compute_Triangle(Triangle, FALSE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transfrom_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Transform_Triangle(Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- TRIANGLE *Triangle = (TRIANGLE *)Object;
-
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
- MTransPoint(Triangle->P1, Triangle->P1, Trans);
- MTransPoint(Triangle->P2, Triangle->P2, Trans);
- MTransPoint(Triangle->P3, Triangle->P3, Trans);
-
- Compute_Triangle(Triangle, FALSE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Invert_Triangle(Object)
- OBJECT *Object;
- {
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- TRIANGLE *Create_Triangle()
- {
- TRIANGLE *New;
-
- New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
-
- INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
-
- Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
-
- New->Distance = 0.0;
-
- Make_Vector(New->P1, 0.0, 0.0, 0.0);
- Make_Vector(New->P2, 1.0, 0.0, 0.0);
- Make_Vector(New->P3, 0.0, 1.0, 0.0);
-
- /*
- * NOTE: Dominant_Axis is computed when Parse_Triangle calls
- * Compute_Triangle. vAxis is used only for smooth triangles.
- */
-
- return(New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void *Copy_Triangle(Object)
- OBJECT *Object;
- {
- TRIANGLE *New;
-
- New = Create_Triangle();
-
- *New = *((TRIANGLE *)Object);
-
- return(New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Destroy_Triangle(Object)
- OBJECT *Object;
- {
- POV_FREE (Object);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Translate_Smooth_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
- VECTOR Translation;
-
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- VEvaluate(Translation, Triangle->Normal_Vector, Vector);
-
- Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
-
- VAddEq(Triangle->P1, Vector);
- VAddEq(Triangle->P2, Vector);
- VAddEq(Triangle->P3, Vector);
-
- Compute_Triangle((TRIANGLE *)Triangle, TRUE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Rotate_Smooth_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Transform_Smooth_Triangle(Object, Trans);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Scale_Smooth_Triangle(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- DBL Length;
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
-
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
- Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
- Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
-
- VLength(Length, Triangle->Normal_Vector);
- VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
- Triangle->Distance /= Length;
-
- VEvaluateEq(Triangle->P1, Vector);
- VEvaluateEq(Triangle->P2, Vector);
- VEvaluateEq(Triangle->P3, Vector);
-
- Compute_Triangle((TRIANGLE *)Triangle,TRUE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transform_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Transform_Smooth_Triangle(Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
-
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
- MTransPoint(Triangle->P1, Triangle->P1, Trans);
- MTransPoint(Triangle->P2, Triangle->P2, Trans);
- MTransPoint(Triangle->P3, Triangle->P3, Trans);
- MTransPoint(Triangle->N1, Triangle->N1, Trans);
- MTransPoint(Triangle->N2, Triangle->N2, Trans);
- MTransPoint(Triangle->N3, Triangle->N3, Trans);
-
- Compute_Triangle((TRIANGLE *)Triangle, TRUE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Invert_Smooth_Triangle(Object)
- OBJECT *Object;
- {
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- SMOOTH_TRIANGLE *Create_Smooth_Triangle()
- {
- SMOOTH_TRIANGLE *New;
-
- New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
-
- INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
-
- Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
-
- New->Distance = 0.0;
-
- Make_Vector(New->P1, 0.0, 0.0, 0.0);
- Make_Vector(New->P2, 1.0, 0.0, 0.0);
- Make_Vector(New->P3, 0.0, 1.0, 0.0);
- Make_Vector(New->N1, 0.0, 1.0, 0.0);
- Make_Vector(New->N2, 0.0, 1.0, 0.0);
- Make_Vector(New->N3, 0.0, 1.0, 0.0);
-
- /*
- * NOTE: Dominant_Axis and vAxis are computed when
- * Parse_Triangle calls Compute_Triangle.
- */
-
- return(New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void *Copy_Smooth_Triangle(Object)
- OBJECT *Object;
- {
- SMOOTH_TRIANGLE *New;
-
- New = Create_Smooth_Triangle();
-
- *New = *((SMOOTH_TRIANGLE *)Object);
-
- return(New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_Triangle_BBox
- *
- * INPUT
- *
- * Triangle - Triangle
- *
- * OUTPUT
- *
- * Triangle
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Calculate the bounding box of a triangle.
- *
- * CHANGES
- *
- * Aug 1994 : Creation.
- *
- ******************************************************************************/
-
- void Compute_Triangle_BBox(Triangle)
- TRIANGLE *Triangle;
- {
- VECTOR Min, Max, Epsilon;
-
- Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
-
- Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
- Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
- Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
-
- Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
- Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
- Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
-
- VSubEq(Min, Epsilon);
- VAddEq(Max, Epsilon);
-
- Make_BBox_from_min_max(Triangle->BBox, Min, Max);
- }
-
-
-